package com.zjpavt.client.hal;

import com.zjpavt.client.udp.artnet.ArtNetServer;
import com.zjpavt.client.udp.artnet.controlPanel.*;
import com.zjpavt.client.util.ClientConfig;
import com.zjpavt.client.util.LoggerUtil;
import com.zjpavt.client.util.PropertiesUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
/**
 * ArtNet 配置类
 * @author zyc
 */
@Slf4j
public class ArtNetConfig {
    public static final String DMX_CONFIG_PROPERTIES = ClientConfig.DMX_CONFIG_PROPERTIES;
    public static final String CONTROLLER_TYPE = "controllerType";
    public static final String EXTERNSTART = "externstart";
    public static final String BEGIN_CHANNEL_INDEX = "beginChannelIndex";
    public static final String CHANNEL_LENGTH = "channelLength";
    public static final String SPEED_KEY = "speed";
    public static final String ARTNET_SERVER_ON = "ON";
    public static final String ARTNET_SERVER_OFF = "OFF";
    public static final String MA_CONTROLLER = "MA";
    public static final String SUITE_CONTROLLER = "Suite";
    public static final String[] TYPE_ARRAY = {ARTNET_SERVER_OFF, ARTNET_SERVER_ON};

    /**
     * 控制台类型
     */
    private static String type;

    /**
     * 取值范围0-255 对应设备的255个域
     */
    private static int externstart;

    /**
     * 起始通道的编号 从0开始
     */
    private static int beginChannelIndex = 0;

    /**
     * 占据的通道长度
     */
    private static int channelLength = 0;

    /**
     * 解析速率
     */
    private static int speed = 1;

    public static int getTypeIndex() {
        for (int i = 0; i < TYPE_ARRAY.length; i++) {
            if (TYPE_ARRAY[i].equals(type)) {
                return i;
            }
        }
        log.error("index out of array");
        return -1;
    }

    public static int getTypeIndex(String sType) {
        for (int i = 0; i < TYPE_ARRAY.length; i++) {
            if (TYPE_ARRAY[i].equals(sType)) {
                return i;
            }
        }
        log.error("index out of array");
        return -1;
    }

    public static String getType() {
        return type;
    }

    public static int getExternstart() {
        return externstart;
    }

    public static int getBeginChannelIndex() {
        return beginChannelIndex;
    }

    public static int getChannelLength() {
        return channelLength;
    }

    public static int getSpeed() {
        return speed;
    }

    public static void setType(String type) {
        if (getTypeIndex(type) >= 0) {
            ArtNetConfig.type = type;
        }
    }

    public static void setExternstart(int externstart) {
        ArtNetConfig.externstart = externstart;
    }

    public static void setBeginChannelIndex(int beginChannelIndex) {
        ArtNetConfig.beginChannelIndex = beginChannelIndex;
    }

    public static void setChannelLength(int channelLength) {
        ArtNetConfig.channelLength = channelLength;
    }

    public static void setSpeed(int speed) {
        ArtNetConfig.speed = speed;
    }

    static {
        init();
    }

    /**
     * 将Config中的控台配置信息加载到Server中
     */
    public static void update() {
        changeControllerParameter(type, speed, externstart, beginChannelIndex, channelLength);
    }
    private static void init() {
        try {
            String sType = PropertiesUtil.getProperties(DMX_CONFIG_PROPERTIES, CONTROLLER_TYPE,TYPE_ARRAY[0]);
            String sExternstart = PropertiesUtil.getProperties(DMX_CONFIG_PROPERTIES, EXTERNSTART,"0");
            String sSpeed = PropertiesUtil.getProperties(DMX_CONFIG_PROPERTIES, SPEED_KEY,"1");
            String sBeginChannelIndex = PropertiesUtil.getProperties(DMX_CONFIG_PROPERTIES, BEGIN_CHANNEL_INDEX,"500");
            String sChannelLength = PropertiesUtil.getProperties(DMX_CONFIG_PROPERTIES, CHANNEL_LENGTH,"12");
            if (ArtNetConfig.getTypeIndex(sType) > 0) {
                setType(sType);
            } else {
                setType(TYPE_ARRAY[0]);
            }
            externstart = Integer.parseInt(sExternstart);
            speed = Integer.parseInt(sSpeed);
            beginChannelIndex = Integer.parseInt(sBeginChannelIndex);
            channelLength = Integer.parseInt(sChannelLength);
        } catch (NumberFormatException | IOException e) {
            log.error(LoggerUtil.convertException2String(e));
        }
    }

    /**
     * 调用时间应该是初始化以及参数修改后
     * 根据参数修改解析的控台参数，传入到artNet信号监听器中
     */
    private static boolean changeControllerParameter(String type, int speed, int externstart, int beginChannelIndex, int channelLength) {
        ControllerFactory controllerFactory = ControllerFactory.getINSATANCE();
        controllerFactory.setType(type);
        controllerFactory.setExternstart(externstart);
        controllerFactory.setSpeed(speed);
        controllerFactory.setBeginChannelIndex(beginChannelIndex);
        controllerFactory.setChannelLength(channelLength);
        AbstractArtNetController artNetController = controllerFactory.build();
        if (artNetController != null) {
            ArtNetServer.getInstance().setArtNetController(artNetController);
            return true;
        } else {
            log.error("can't get controller by type:" + type + " speed: " + speed + "externstart:" + externstart
                      + " begin:" + beginChannelIndex + " length:" + channelLength);
            return false;
        }
    }

    /**
     * 保存页面端传过来的控台参数
     * @param type
     * @param speed
     * @param externstart
     * @param beginChannelIndex
     * @param channelLength
     */
    public static void saveValue(String type, int speed, int externstart, int beginChannelIndex, int channelLength) {
        try {
//           验证不通过的时候回抛出AssertError 或者返回false 则数据不保存
            if (changeControllerParameter(type,speed,externstart,beginChannelIndex,channelLength)) {
                setType(type);
                setSpeed(speed);
                setBeginChannelIndex(beginChannelIndex);
                setChannelLength(channelLength);
                setExternstart(externstart);
                saveParameter2Properties(type, speed, externstart, beginChannelIndex, channelLength);
            }
        } catch (IOException e) {
            log.error(LoggerUtil.convertException2String(e));
        }
    }

    /**
     * 保存到properties文件
     * @param type
     * @param speed
     * @param externstart
     * @param beginChannelIndex
     * @param channelLength
     * @throws IOException
     */
    private static void saveParameter2Properties(String type, int speed, int externstart, int beginChannelIndex, int channelLength) throws IOException {
        PropertiesUtil.setPropertyOrReplace(DMX_CONFIG_PROPERTIES,CONTROLLER_TYPE,type);
        PropertiesUtil.setPropertyOrReplace(DMX_CONFIG_PROPERTIES,EXTERNSTART,String.valueOf(externstart));
        PropertiesUtil.setPropertyOrReplace(DMX_CONFIG_PROPERTIES,SPEED_KEY,String.valueOf(speed));
        PropertiesUtil.setPropertyOrReplace(DMX_CONFIG_PROPERTIES,BEGIN_CHANNEL_INDEX,String.valueOf(beginChannelIndex));
        PropertiesUtil.setPropertyOrReplace(DMX_CONFIG_PROPERTIES,CHANNEL_LENGTH,String.valueOf(channelLength));
    }

    public static String[] getTypeArray() {
        return TYPE_ARRAY;
    }
}
